package com.cx.utils;

import org.springframework.data.redis.core.DefaultTypedTuple;

import java.util.*;

public class SerializeUtil {

	public static <T> T parse(Object result, Class<?> clazz) {

		if (result == null || !isDiffType(clazz)) {
			return (T) result;
		}

		if (isLongType(clazz) && isIntegerType(result.getClass())) {
			result = new Long(result.toString());

		} else if (isShortType(clazz) && isIntegerType(result.getClass())) {
			result = new Short(result.toString());

		} else if (isByteType(clazz) && isIntegerType(result.getClass())) {
			result = new Byte((byte) (int) result);

		} else if (isFloatType(clazz) && isDoubleType(result.getClass())) {
			result = new Double(result.toString());

		} else if (isCharType(clazz) && isStringType(result.getClass())) {
			char[] strChars = result.toString().toCharArray();
			if (strChars.length == 1) {
				result = strChars[0];
			}
		}
		return (T) result;
	}

	
	public static <T> List<T> parseList(List<T> list, Class<?> clazz) {
		if (list == null || !isDiffType(clazz)) {
			return list;
		}
		List<T> resultList = new ArrayList<>();
		for(Object result : list) {
			T t = parse(result, clazz);
			resultList.add(t);
		}
		return resultList;
	}
	
	
	public static <T> Set<T> parseSet(Set<T> set, Class<?> clazz) {
		if (set == null || !isDiffType(clazz)) {
			return set;
		}
		Set<T> resultSet = new LinkedHashSet<>();
		for(Object result : set) {
			T t = parse(result, clazz);
			resultSet.add(t);
		}
		return resultSet;
	}
	
	
	public static <T> Set<DefaultTypedTuple<T>> parseTupleSet(Set<DefaultTypedTuple<T>> set, Class<?> clazz) {
		if (set == null || !isDiffType(clazz)) {
			return set;
		}
		Set<DefaultTypedTuple<T>> resultSet = new LinkedHashSet<>();
		for(DefaultTypedTuple<T> result : set) {
			T t = parse(result.getValue(), clazz);
			resultSet.add(new DefaultTypedTuple<>(t, result.getScore()));
		}
		return resultSet;
	}
	
	
	public static <T> Map<String, T> parseMap(Map<String, T> map, Class<?> clazz) {
		if (map == null || !isDiffType(clazz)) {
			return map;
		}
		Map<String, T> resultMap = new HashMap<>();
		
		for(String key : map.keySet()) {
			Object result = map.get(key);
			T t = parse(result, clazz);
			resultMap.put(key, t);
		}
		return resultMap;
	}
	
	

	public static boolean isStringType(Class<?> clazz) {
		return clazz == String.class;
	}

	public static boolean isIntegerType(Class<?> clazz) {
		return clazz == int.class || clazz == Integer.class;
	}

	public static boolean isLongType(Class<?> clazz) {
		return clazz == long.class || clazz == Long.class;
	}

	public static boolean isDoubleType(Class<?> clazz) {
		return clazz == double.class || clazz == Double.class;
	}

	public static boolean isFloatType(Class<?> clazz) {
		return clazz == float.class || clazz == Float.class;
	}

	public static boolean isCharType(Class<?> clazz) {
		return clazz == char.class || clazz == Character.class;
	}

	public static boolean isByteType(Class<?> clazz) {
		return clazz == byte.class || clazz == Byte.class;
	}

	public static boolean isShortType(Class<?> clazz) {
		return clazz == short.class || clazz == Short.class;
	}
	
	
	/**
	 * 是否含有反序列化歧异的类型
	 */
	private static boolean isDiffType(Class<?> clazz) {
		return isLongType(clazz) || isShortType(clazz) || isByteType(clazz) || isFloatType(clazz) || isCharType(clazz);
	}
}